package com.teamwhole.modules.sys.utils;

import java.util.List;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;

import com.teamwhole.common.utils.CacheUtils;
import com.teamwhole.common.utils.SpringContextHolder;
import com.teamwhole.modules.sys.dao.DepartmentDao;
import com.teamwhole.modules.sys.dao.MenuDao;
import com.teamwhole.modules.sys.dao.RoleDao;
import com.teamwhole.modules.sys.dao.UserDao;
import com.teamwhole.modules.sys.entity.Department;
import com.teamwhole.modules.sys.entity.Menu;
import com.teamwhole.modules.sys.entity.Role;
import com.teamwhole.modules.sys.entity.User;
import com.teamwhole.modules.sys.security.SystemAuthorizingRealm.Principal;

/**
 * 用户工具类
 * Created by ZGJ
 */
public class UserUtils {

	private static UserDao userDao = SpringContextHolder.getBean(UserDao.class);
	private static RoleDao roleDao = SpringContextHolder.getBean(RoleDao.class);
	private static MenuDao menuDao = SpringContextHolder.getBean(MenuDao.class);
	private static DepartmentDao deptDao = SpringContextHolder.getBean(DepartmentDao.class);

	public static final String USER_CACHE = "userCache";
	public static final String USER_CACHE_ID_ = "id_";
	public static final String USER_CACHE_LOGIN_NAME_ = "ln";
	public static final String USER_CACHE_LIST_BY_DEPT_ID_ = "d_id_";
	public static final String CACHE_ROLE_LIST = "roleList";
	public static final String CACHE_MENU_LIST = "menuList";
	public static final String CACHE_DEPT_LIST = "deptList";
	
	// -- User --//
	
	/** 获取当前登录用户 **/
    public static User getUser() {
        User user = new User();
        Principal principal = getPrincipal();
        if (principal != null) {
            user = findByLoginName(principal.getLoginName());
        }
        return user;
    }
	
    /** 根据ID获取用户 **/
    public static User get(String id) {
        User user = (User) CacheUtils.get(USER_CACHE, USER_CACHE_ID_ + id);
        if (user == null) {
            user = userDao.get(new User(id));
            if (user != null) {
                user.setRoleList(roleDao.findList(new Role(user)));
                // CACHE
                //CacheUtils.put(USER_CACHE, USER_CACHE_ID_ + user.getId(), user);
                //CacheUtils.put(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginName(), user);
            }
        }
        return user;
    }

    /** 根据登录名获取用户 **/
    public static User findByLoginName(String loginName) {
        User user = userDao.findByLoginName(new User(null, loginName));
        if (user != null) {
            user.setRoleList(roleDao.findList(new Role(user)));
            // CACHE
            //CacheUtils.put(USER_CACHE, USER_CACHE_ID_ + user.getId(), user);
            //CacheUtils.put(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginName(), user);
        }
        return user;
    }
    
    /** 获取当前登录者对象 **/
    public static Principal getPrincipal() {
        try {
            Subject subject = SecurityUtils.getSubject();
            return (Principal) subject.getPrincipal();
        } catch (Exception e) {
        }
        return null;
    }
    
    /** 清除当前用户缓存 **/
    public static void clearCache() {
        removeCache(CACHE_ROLE_LIST);
        removeCache(CACHE_MENU_LIST);
        removeCache(CACHE_DEPT_LIST);
        UserUtils.clearCache(getUser());
    }

    /** 清除指定用户缓存 **/
    public static void clearCache(User user) {
        CacheUtils.remove(USER_CACHE, USER_CACHE_ID_ + user.getId());
        CacheUtils.remove(USER_CACHE, USER_CACHE_LOGIN_NAME_ + user.getLoginName());
        if (user.getDept() != null && user.getDept().getId() != null) {
            CacheUtils.remove(USER_CACHE, USER_CACHE_LIST_BY_DEPT_ID_ + user.getDept().getId());
        }
    }
    
    // -- Role --//
    
    /** 获取当前用户角色列表 **/
    public static List<Role> getRoleList() {
        @SuppressWarnings("unchecked")
        List<Role> roleList = (List<Role>) getCache(CACHE_ROLE_LIST);
        if (roleList == null) {
            User user = getUser();
            if (user.isAdmin()) {
                roleList = roleDao.findAllList(new Role());
            } else {
                // TODO 获取当前用户所在部门的角色
                Role role = new Role();
                role.setUser(user);
                roleList = roleDao.findList(role);
            }
            // CACHE
            //putCache(CACHE_ROLE_LIST, roleList);
        }
        return roleList;
    }

    // -- Menu --//
    
    /** 获取当前用户授权菜单 **/
    public static List<Menu> getMenuList() {
        @SuppressWarnings("unchecked")
        List<Menu> menuList = (List<Menu>) getCache(CACHE_MENU_LIST);
        if (menuList == null) {
            User user = getUser();
            if (user.isAdmin()) {
                menuList = menuDao.findAllList(new Menu());
            } else {
                Menu menu = new Menu();
                menu.setUserId(user.getId());
                menuList = menuDao.findByUserId(menu);
            }
            //putCache(CACHE_MENU_LIST, menuList);
        }
        return menuList;
    }
    
    // -- Dept --//
    
    /** 获取所有部门 **/
    public static List<Department> getDeptList() {
        @SuppressWarnings("unchecked")
        List<Department> deptList = (List<Department>) getCache(CACHE_DEPT_LIST);
        if (deptList == null) {
            User user = getUser();
            if (user.isAdmin()) {
                deptList = deptDao.findAllList(new Department());
            } else {
                Department dept = new Department();
                // TODO 用户设置 过滤
                deptList = deptDao.findList(dept);
            }
            //putCache(CACHE_DEPT_LIST, deptList);
        }
        return deptList;
    }
    
    /** 获取授权主要对象 **/
    public static Subject getSubject() {
        return SecurityUtils.getSubject();
    }

	/** 获取当前Session **/
    public static Session getSession() {
        try {
            Subject subject = SecurityUtils.getSubject();
            Session session = subject.getSession(false);
            if (session == null) {
                session = subject.getSession();
            }
            return session;
        } catch (InvalidSessionException e) {
        }
        return null;
    }

	// ============== User Cache ============== //
    
	public static Object getCache(String key) {
		return getCache(key, null);
	}

	public static Object getCache(String key, Object defaultValue) {
		Object obj = getSession().getAttribute(key);
		return (obj == null ? defaultValue : obj);
	}

	public static void putCache(String key, Object value) {
		getSession().setAttribute(key, value);
	}

	public static void removeCache(String key) {
		getSession().removeAttribute(key);
	}

}